const WxRequest = require('./request');
const Config = require('@/config/base_config');
const Storage = require('@/utils/storage');
const Toast = require('@/utils/toast');
const Util = require('./../utils/util.js')
const {
  checkTokenExpiration
} = require('@/utils/auth');


/**
 * 刷新 Token
 */
const refreshAccessToken = (refreshToken) => {
  return new Promise((resolve, reject) => {
    wx.request({
      url: `${Config.API_HOST}/api/auth/refresh`,
      method: 'POST',
      data: {
        refreshToken
      }, // 传递 refreshToken
      success: (res) => {
        if (res.data.code === 200) {
          accessToken = res.data.accessToken;
          refreshToken = res.data.refreshToken;
          wx.setStorageSync('accessToken', accessToken);
          wx.setStorageSync('refreshToken', refreshToken);
          resolve(res);
        } else {
          reject(new Error('刷新 Token 失败'));
        }
      },
      fail: (err) => reject(err),
    });
  });
};


class HttpInterceptor {
  constructor(httpInstance) {
    this.http = httpInstance;
    this.isRefreshing = false;
    this.requestsQueue = [];
  }

  /**
   * 刷新Token
   * @returns {Promise<string|null>} 返回新的token或null
   */
  async refreshToken() {
    if (this.isRefreshing) {
      return new Promise((resolve) => {
        this.requestsQueue.push(resolve);
      });
    }

    try {
      this.isRefreshing = true;
      const refreshToken = Storage.get('refresh_token');
      console.log("refreshToken", refreshToken)
      if (!refreshToken) {
        throw new Error('缺少refreshToken');
        // --登录过期，直接跳转登录页面
      }
      await refreshAccessToken(refreshToken).then((response) => {
        try {
          if (!response.data?.access_token) {
            throw new Error('无效的Token响应');
          }

          let expires_in = Util.timeToSeconds(response.data.expires_in);
          Storage.set('access_token', response.data.access_token, expires_in);

          this.requestsQueue.forEach(cb => cb(response.data.access_token));
          this.requestsQueue = [];

          return response.data.access_token;
        } catch (error) {
          throw new Error(error)
          return null;
        }
      });
    } catch (error) {
      console.log('刷新Token失败:', error);

      Storage.remove('access_token');
      Storage.remove('refresh_token');
      this.requestsQueue.forEach(cb => cb(null));
      this.requestsQueue = [];

      return null;
    } finally {
      this.isRefreshing = false;
    }
  }

  async handleResponse(response) {
    console.log(response);
    try {
      if (response.statusCode === 200) {
        return response.data;
      }

      if (response.statusCode === 408 || response.errMsg?.includes('timeout')) {
        return await this.handleTimeout(response);
      }

      if (response.statusCode === 401) {
        return await this.handleTokenExpired(response);
      }

      if (response.statusCode >= 500) {
        return await this.handleServerError(response);
      }
      if (!response.statusCode || response.statusCode === 0) {
        return await this.handleNetworkError(response);
      }
      throw response.data || {
        code: response.statusCode,
        message: '请求失败',
        config: response.config
      };
    } catch (error) {
      return await this.handleError(error);
    }
  }

  async handleTimeout(response) {
    const maxRetries = response.config.retry || 0;

    if (maxRetries > 0 && response.config._retryCount < maxRetries) {
      response.config._retryCount = (response.config._retryCount || 0) + 1;
      return new Promise(resolve => {
        setTimeout(() => {
          resolve(this.http.request(response.config));
        }, 1000 * response.config._retryCount);
      });
    }

    Toast.showError('请求超时，请稍后重试');
    throw {
      code: 408,
      message: '请求超时',
      config: response.config
    };
  }

  async handleNetworkError(response) {
    const networkType = await this.checkNetwork();
    console.log(networkType)
    let errorMessage = '数据请求地址有误，请检查网络连接';

    if (networkType === 'none') {
      // 等待2秒后重试一次
      await new Promise(resolve => setTimeout(resolve, 2000));
      const retryStatus = await this.checkNetwork();
      if (retryStatus === 'none') {
        this.showNetworkSetting();
        throw {
          code: 0,
          message: '网络连接已断开',
          config: response.config
        };
      }
    }

    // 如果是首次请求失败，自动重试
    if (!response.config._retried) {
      response.config._retried = true;
      return new Promise(resolve => {
        setTimeout(() => {
          resolve(this.http.request(response.config));
        }, 1000);
      });
    }
    throw {
      code: 0,
      message: errorMessage,
      config: response.config
    };
  }

  async handleTokenExpired(response) {
    try {
      const newToken = await this.refreshToken();
      if (newToken) {
        const originalRequest = response.config;
        originalRequest.header.Authorization = `Bearer ${newToken}`;
        console.log(originalRequest)
        return this.http.request(originalRequest);
      }
      throw new Error('登录已过期');
    } catch (error) {
      this.redirectToLogin();
      throw {
        code: 401,
        message: '登录已过期，请重新登录',
        config: response.config
      };
    }
  }

  handleServerError(response) {
    Toast.showError('服务器繁忙，请稍后重试');
    throw {
      code: response.statusCode,
      message: '服务器错误',
      data: response.data,
      config: response.config
    };
  }

  handleError(error) {
    if (!error.config || !error.config.skipErrorToast) {
      Toast.showError(error.message || '请求失败');
    }

    if (error.code === 401) {
      this.redirectToLogin();
    }

    throw error;
  }

  checkNetwork() {
    return new Promise(resolve => {
      wx.getNetworkType({
        success: res => resolve(res.networkType),
        fail: () => resolve('unknown')
      });
    });
  }

  showNetworkSetting() {
    setTimeout(() => {
      wx.showModal({
        title: '网络不可用',
        content: '当前网络已断开，是否前往设置？',
        confirmText: '去设置',
        success: (res) => {
          if (res.confirm) {
            wx.openSetting();
          }
        }
      });
    }, 500);
  }

  redirectToLogin() {
    setTimeout(() => {
      const pages = getCurrentPages();
      const currentPage = pages[pages.length - 1];
      const currentRoute = currentPage.route;
      const currentOptions = currentPage.options || {};
      console.log(`/pages/login/index?redirect=${encodeURIComponent(currentRoute)}&params=${encodeURIComponent(JSON.stringify(currentOptions))}`)
      wx.redirectTo({
        url: `/pages/login/index?redirect=${encodeURIComponent(currentRoute)}&params=${encodeURIComponent(JSON.stringify(currentOptions))}`
      });
    }, 1500);
  }
}

// 创建实例
const http = new WxRequest({
  baseURL: Config.API_HOST,
  timeout: 30000
});

// 创建拦截器实例
const interceptor = new HttpInterceptor(http);

// 设置拦截器
http.interceptors.request = function (config) {

  if (!config.skipAuth) {
    const token = Storage.get('access_token');
    if (checkTokenExpiration(token)) {
      config._needsTokenRefresh = true;
    }
    if (token) {
      config.header.Authorization = `Bearer ${token}`;
    }
  }
  return config;
};

http.interceptors.response = async function (response) {
  return interceptor.handleResponse(response);
};

module.exports = http;